home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 5 / MacMania 5.toast / / Internet software / NewsWatcher / NW Source / Source / prefsdlog.c < prev    next >
Text File  |  1997-01-09  |  66KB  |  2,346 lines

  1. /*----------------------------------------------------------------------------
  2.  
  3.     prefsdlog.c
  4.  
  5.     This module handles the preferences dialog.
  6.     
  7.     Copyright © 1994-1997, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. #include "glob.h"
  16. #include "prefsdlog.h"
  17. #include "dialog.h"
  18. #include "popuputil.h"
  19. #include "sfutil.h"
  20. #include "log.h"
  21. #include "news.h"
  22. #include "newswatcher.h"
  23. #include "strutil.h"
  24. #include "full.h"
  25. #include "drawutil.h"
  26. #include "memutil.h"
  27. #include "fileutil.h"
  28. #include "apputil.h"
  29. #include "resutil.h"
  30. #include "menus.h"
  31. #include "url.h"
  32. #include "ic.h"
  33. #include "header.h"
  34. #include "qsort.h"
  35. #include "arrowpair.h"
  36. #include "biglist.h"
  37.  
  38.  
  39.  
  40. /* Items common to all topics. The kInit and kTerm items are pseudo-items
  41.    used to intialize and terminate the topics. The OK and Cancel buttons
  42.    are also common to all topics (item numbers 1 and 2). Items 3 through
  43.    7 are user items to draw the 5 segments of the gray outline. Item 8
  44.    is the topic popup menu. Item 9 is the user item for the up and down
  45.    arrow controls. Item 10 is the help item for help balloons. Item 11 is 
  46.    the user item to outline the OK button. */
  47.  
  48. #define kInit                100
  49. #define kTerm                101
  50. #define kFirstGrayLine        3
  51. #define kLastGrayLine        7
  52. #define kTopicPopup            8
  53. #define kArrows                9
  54. #define kCommonItems        11
  55.  
  56. /* Prefs dialog and DITL resources */
  57.  
  58. #define kPrefsDlg                300
  59. #define kNewsreadingOptions        1
  60. #define kServerAddresses        2
  61. #define kServerOptions            3
  62. #define kPersonalInfo            4
  63. #define kSignature                5
  64. #define kMessageOptions            6
  65. #define kExtraHeaderLines        7
  66. #define kRemoteHost                8
  67. #define kScreenFonts            9
  68. #define kPrintingFont            10
  69. #define kSavedUserGroupLists    11
  70. #define kSavedArticles            12
  71. #define kSavedMessages            13
  72. #define kURLHelpers                14
  73. #define kAuthentication            15
  74. #define kExtractBinaries        16
  75. #define kMiscOptions            17
  76.  
  77. #define kNumTopics                17
  78.  
  79. /* Newsreading options topic. */
  80.  
  81. #define kShowAuthors            (kCommonItems + 1)
  82. #define kShowArtHeaders            (kCommonItems + 2)
  83. #define kCollapseThreads        (kCommonItems + 3)
  84. #define kKeyboardShortcuts        (kCommonItems + 4)
  85. #define kKeypadShortcuts        (kCommonItems + 5)
  86. #define kReuseArticleWinds        (kCommonItems + 6)
  87. #define kReturnToSubjectWindow    (kCommonItems + 7)
  88. #define kStopAtEndOfSubjectList    (kCommonItems + 8)
  89. #define kBeepAtEndOfLists        (kCommonItems + 9)
  90. #define kMaxArticles            (kCommonItems + 11)
  91.  
  92. /* Server info topic. */
  93.  
  94. #define kNewsServer            (kCommonItems + 3)
  95. #define kMailServer            (kCommonItems + 5)
  96.  
  97. /* Server options topic. */
  98.  
  99. #define kBatchedGroupCmds    (kCommonItems + 2)
  100. #define kUseXPAT            (kCommonItems + 3)
  101. #define kNoNewConnection    (kCommonItems + 4)
  102. #define kNoModeReader        (kCommonItems + 5)
  103.  
  104. /* Personal info topic. */
  105.  
  106. #define kFullName            (kCommonItems + 3)
  107. #define kOrganization        (kCommonItems + 5)
  108. #define kMailAddress        (kCommonItems + 7)
  109.  
  110. /* Signature topic. */
  111.  
  112. #define kSigStaticText        (kCommonItems + 1)
  113. #define kSignatureEditText    (kCommonItems + 2)
  114. #define kAddSigBlankLine    (kCommonItems + 3)
  115. #define kAddSigSeparator    (kCommonItems + 4)
  116.  
  117. /* Message options topic. */
  118.  
  119. #define kMsgReplyPost        (kCommonItems + 1)
  120. #define kMsgReplyEmail        (kCommonItems + 2)
  121. #define kMsgCopySelf        (kCommonItems + 3)
  122. #define kMsgShowMsgDetails    (kCommonItems + 4)
  123. #define kMsgWrapOnSend        (kCommonItems + 5)
  124. #define kMsgShowLabels        (kCommonItems + 6)
  125. #define kMsgTabEnabled        (kCommonItems + 7)
  126. #define kMsgTabStops        (kCommonItems + 9)
  127. #define kMsgQuoteString        (kCommonItems + 11)
  128.  
  129. /* Extra header lines topic */
  130.  
  131. #define kMsgExtraNewsHdrLines    (kCommonItems + 2)
  132. #define kMsgExtraMailHdrLines    (kCommonItems + 4)
  133.  
  134. /* Remote host info topic. */
  135.  
  136. #define    kRemoteHostAddr        (kCommonItems + 3)
  137. #define    kRemoteLogin        (kCommonItems + 5)
  138. #define    kRemotePassword        (kCommonItems + 7)
  139. #define kRemotePath            (kCommonItems + 9)
  140. #define kAutoGetPut            (kCommonItems + 10)
  141. #define    kSavePassword        (kCommonItems + 11)
  142.  
  143. /* Screen fonts topic. */
  144.  
  145. #define kListFontPopup         (kCommonItems + 2)
  146. #define kListSizeBox        (kCommonItems + 4)
  147. #define kListSizePopup        (kCommonItems + 5)
  148. #define kListSample            (kCommonItems + 6)
  149. #define kListVertLine        (kCommonItems + 7)
  150. #define kTextFontPopup        (kCommonItems + 9)
  151. #define kTextSizeBox        (kCommonItems + 11)
  152. #define kTextSizePopup        (kCommonItems + 12)
  153. #define kTextSample            (kCommonItems + 13)
  154.  
  155. /* Printing font topic. */
  156.  
  157. #define kPrintingFontPopup         (kCommonItems + 1)
  158. #define kPrintingSizeBox        (kCommonItems + 3)
  159. #define kPrintingSizePopup        (kCommonItems + 4)
  160. #define kPrintingSample            (kCommonItems + 5)
  161.  
  162. /* Saved user group lists topic. */
  163.  
  164. #define kSavedUGLDirCheckBox    (kCommonItems + 1)
  165. #define kSavedUGLDirBorder        (kCommonItems + 2)
  166. #define kSavedUGLDirName        (kCommonItems + 3)
  167. #define kSavedUGLDirButton        (kCommonItems + 4)
  168. #define kSavedUGLAutoSaveOnQuit    (kCommonItems + 5)
  169.  
  170. /* Saved articles topic. */
  171.  
  172. #define kSavedArtAppBorder        (kCommonItems + 2)
  173. #define kSavedArtAppName        (kCommonItems + 3)
  174. #define kSavedArtAppButton        (kCommonItems + 4)
  175. #define kSavedArtDirCheckBox     (kCommonItems + 5)
  176. #define kSavedArtDirBorder        (kCommonItems + 6)
  177. #define kSavedArtDirName        (kCommonItems + 7)
  178. #define kSavedArtDirButton        (kCommonItems + 8)
  179. #define kSavedArtSepFiles        (kCommonItems + 9)
  180. #define kSavedArtAutoAppend        (kCommonItems + 10)
  181. #define kSavedArtSaveEncoded    (kCommonItems + 11)
  182.  
  183. /* Saved messages topic. */
  184.  
  185. #define kSavedMsgDirCheckBox     (kCommonItems + 1)
  186. #define kSavedMsgDirBorder        (kCommonItems + 2)
  187. #define kSavedMsgDirName        (kCommonItems + 3)
  188. #define kSavedMsgDirButton        (kCommonItems + 4)
  189. #define kSavedMsgDelAfterSend    (kCommonItems + 5)
  190.  
  191. /* URL helper programs topic. */
  192.  
  193. #define kURLList            (kCommonItems + 1)
  194. #define kURLChangeButton    (kCommonItems + 2)
  195. #define kURLDeleteButton    (kCommonItems + 3)
  196. #define kURLNewScheme        (kCommonItems + 5)
  197. #define kURLAddButton        (kCommonItems + 6)
  198. #define kURLUseWebHelper    (kCommonItems + 7)
  199.  
  200. /* Authentication topic. */
  201.  
  202. #define kAuthUsername        (kCommonItems + 3)
  203. #define kAuthPassword        (kCommonItems + 5)
  204. #define kAuthSavePassword    (kCommonItems + 6)
  205. #define kAuthPrivateGroups    (kCommonItems + 7)
  206. #define kAuthWhenRequested    (kCommonItems + 8)
  207. #define kAuthAtStartup        (kCommonItems + 9)
  208.  
  209. /* Extracting Binaries topic. */
  210.  
  211. #define kSavedBinDirCheckBox    (kCommonItems + 1)
  212. #define kSavedBinDirBorder        (kCommonItems + 2)
  213. #define kSavedBinDirName        (kCommonItems + 3)
  214. #define kSavedBinDirButton        (kCommonItems + 4)
  215. #define kHqxAppBorder            (kCommonItems + 6)
  216. #define kHqxAppName                (kCommonItems + 7)
  217. #define kHqxAppButton            (kCommonItems + 8)
  218. #define kUUAppBorder            (kCommonItems + 10)
  219. #define kUUAppName                (kCommonItems + 11)
  220. #define kUUAppButton            (kCommonItems + 12)
  221.  
  222. /* Miscellaneous options topic. */
  223.  
  224. #define kReZoomWindows            (kCommonItems + 1)
  225. #define kCheckNewGroups            (kCommonItems + 2)
  226. #define kAreYouSure                (kCommonItems + 3)
  227. #define kLogActionsToFile        (kCommonItems + 4)
  228. #define kDontCoverFinderIcons    (kCommonItems + 5)
  229. #define kUseInternetConfig        (kCommonItems + 6)
  230.  
  231.  
  232.  
  233. static short gItem;                /* dialog item number hit */
  234.  
  235. static ArrowPairRef gArrowPair = nil;    /* arrow pair reference */
  236.  
  237. static Str255 gStaticText;        /* static text for signature dialog */
  238.  
  239. static short gListFontID;        /* current list font id */
  240. static short gListFontSize;        /* current list font size */
  241. static short gTextFontID;        /* current text font id */
  242. static short gTextFontSize;        /* current text font size */
  243. static short gPrintingFontID;    /* current printing font id */
  244. static short gPrintingFontSize;    /* current printing font size */
  245.  
  246. static BigListRef gURLList;        /* URL helpers list ref */
  247. static Handle gURLListStrings;    /* handle to URL helpers list strings */
  248.  
  249. static Boolean gScreenFontsTopic;    /* true if screen fonts topic, false if printing font topic */
  250.  
  251. static Boolean gValid;                /* Set to false by topic handling function
  252.                                        on kTerm call if one of the prefs values
  253.                                        is invalid. */
  254.  
  255. static FileFilterYDUPP gInvisibleFilesFilterUPP = nil;
  256. static UserItemUPP gDrawFontSampleUPP = nil;
  257. static UserItemUPP gDlgArrowsItemUPP = nil;
  258. static UserItemUPP gDrawURLListUPP = nil;
  259.  
  260.  
  261.  
  262. /*----------------------------------------------------------------------------
  263.     ValidHelper
  264.  
  265.     Check for a valid helper program.
  266.     
  267.     Entry:    fSpec = pointer to helper program file spec.
  268.     
  269.     Exit:    function result = true if helper is valid.
  270.             *fSpec = pointer to file spec for copy of helper program which
  271.                 will actually be used if duplicate copies of helper found.
  272. ----------------------------------------------------------------------------*/
  273.  
  274. static Boolean ValidHelper (FSSpec *fSpec)
  275. {
  276.     OSErr err = noErr;
  277.     FInfo fInfo;
  278.     FSSpec file;
  279.     CStr255 fmt, msg;
  280.  
  281.     err = FSpGetFInfo(fSpec, &fInfo);
  282.     if (err != noErr) goto exit1;
  283.     if (fInfo.fdType != 'APPL') goto exit2;
  284.     err = FindAppFromSig(fInfo.fdCreator, &file, nil, nil);
  285.     if (err == fnfErr) goto exit3;
  286.     if (err != noErr) goto exit1;
  287.     if (!IsEqualFSSpec(fSpec, &file)) goto exit4;
  288.     return true;
  289.     
  290. exit1:
  291.     
  292.     GetCString(kStrUnexpectedErr, fmt);
  293.     sprintf(msg, fmt, err);
  294.     StopAlertMessage(msg);
  295.     return false;
  296.     
  297. exit2:
  298.  
  299.     StopAlertNumber(kStrNotAnApplication);
  300.     return false;
  301.     
  302. exit3:
  303.  
  304.     StopAlertNumber(kStrDesktopDatabaseDamaged);
  305.     return true;
  306.     
  307. exit4:
  308.  
  309.     CautionAlertNumber(kStrDuplicateCopiesOfHelper);
  310.     *fSpec = file;
  311.     return true;
  312. }
  313.  
  314.  
  315.  
  316. /*----------------------------------------------------------------------------
  317.     NewsreadingOptions
  318.  
  319.     Handle the newsreading options preferences dialog.
  320.     
  321.     Entry:    prefs = pointer to new prefs.
  322.             dlg = pointer to dialog.
  323.             item = item number hit.
  324.             
  325.     Exit:    function result = error code.
  326. ----------------------------------------------------------------------------*/
  327.  
  328. static OSErr NewsreadingOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  329. {
  330.     long maxFetch;
  331.  
  332.     switch (item) {
  333.     
  334.         case kInit:
  335.         
  336.             DlgSetCheck(dlg, kShowAuthors, prefs->showAuthors);
  337.             DlgSetCheck(dlg, kShowArtHeaders, prefs->showArtHeaders);
  338.             DlgSetCheck(dlg, kCollapseThreads, prefs->showThreadsCollapsed);
  339.             DlgSetCheck(dlg, kKeyboardShortcuts, prefs->keyboardShortcuts);
  340.             DlgSetCheck(dlg, kKeypadShortcuts, prefs->keypadShortcuts);
  341.             DlgSetCheck(dlg, kReuseArticleWinds, prefs->reuseArticleWinds);
  342.             DlgSetCheck(dlg, kReturnToSubjectWindow, prefs->returnToSubjectWindow);
  343.             DlgSetCheck(dlg, kStopAtEndOfSubjectList, prefs->stopAtEndOfSubjectList);
  344.             DlgSetCheck(dlg, kBeepAtEndOfLists, prefs->beepAtEndOfLists);
  345.             DlgSetNumber(dlg, kMaxArticles, prefs->maxFetch);
  346.             SetItemNumeric(dlg, kMaxArticles);
  347.             SetItemMaxLength(dlg, kMaxArticles, 6);
  348.             SelectDialogItemText(dlg, kMaxArticles, 0, kMaxShort);
  349.             break;
  350.             
  351.         case kTerm:
  352.             
  353.             prefs->showAuthors = DlgGetCheck(dlg, kShowAuthors);
  354.             prefs->showArtHeaders = DlgGetCheck(dlg, kShowArtHeaders);
  355.             prefs->showThreadsCollapsed = DlgGetCheck(dlg, kCollapseThreads);
  356.             prefs->keyboardShortcuts = DlgGetCheck(dlg, kKeyboardShortcuts);
  357.             prefs->keypadShortcuts = DlgGetCheck(dlg, kKeypadShortcuts);
  358.             prefs->reuseArticleWinds = DlgGetCheck(dlg, kReuseArticleWinds);
  359.             prefs->returnToSubjectWindow = DlgGetCheck(dlg, kReturnToSubjectWindow);
  360.             prefs->stopAtEndOfSubjectList = DlgGetCheck(dlg, kStopAtEndOfSubjectList);
  361.             prefs->beepAtEndOfLists = DlgGetCheck(dlg, kBeepAtEndOfLists);
  362.             maxFetch = DlgGetNumber(dlg, kMaxArticles);
  363.             if (maxFetch <= 0 || maxFetch > kMaxMaxFetch) maxFetch = kMaxMaxFetch;
  364.             prefs->maxFetch = maxFetch;
  365.             break;
  366.             
  367.         case kShowAuthors:
  368.         case kShowArtHeaders:
  369.         case kCollapseThreads:
  370.         case kKeyboardShortcuts:
  371.         case kKeypadShortcuts:
  372.         case kReuseArticleWinds:
  373.         case kReturnToSubjectWindow:
  374.         case kStopAtEndOfSubjectList:
  375.         case kBeepAtEndOfLists:
  376.         
  377.             DlgToggleCheck(dlg, item);
  378.             break;
  379.             
  380.     }
  381.     
  382.     return noErr;
  383. }
  384.  
  385.  
  386.  
  387. /*----------------------------------------------------------------------------
  388.     Server
  389.  
  390.     Handles the server info preferences dialog.
  391.     
  392.     Entry:    prefs = pointer to new prefs.
  393.             dlg = pointer to dialog.
  394.             item = item number hit.
  395.             
  396.     Exit:    function result = error code.
  397. ----------------------------------------------------------------------------*/
  398.  
  399. static OSErr Server (TPrefRec *prefs, DialogPtr dlg, short item)
  400. {
  401.     Boolean enable;
  402.  
  403.     switch (item) {
  404.     
  405.         case kInit:
  406.         
  407.             DlgSetPString(dlg, kNewsServer, prefs->newsServerName);
  408.             SetItemHostAddress(dlg, kNewsServer);
  409.             SetItemMaxLength(dlg, kNewsServer, 255);
  410.             DlgSetPString(dlg, kMailServer, prefs->mailServerName);
  411.             SetItemHostAddress(dlg, kMailServer);
  412.             SetItemMaxLength(dlg, kMailServer, 255);
  413.             if (*prefs->newsServerName == 0) {
  414.                 SelectDialogItemText(dlg, kNewsServer, 0, 0);
  415.             } else if (*prefs->mailServerName == 0) {
  416.                 SelectDialogItemText(dlg, kMailServer, 0, 0);
  417.             } else {
  418.                 SelectDialogItemText(dlg, kNewsServer, 0, kMaxShort);
  419.             }
  420.             break;
  421.             
  422.         case kTerm:
  423.             
  424.             break;
  425.             
  426.         case kNewsServer:
  427.         case kMailServer:
  428.         
  429.             DlgGetPString(dlg, kNewsServer, prefs->newsServerName);
  430.             DlgGetPString(dlg, kMailServer, prefs->mailServerName);
  431.             enable = *prefs->newsServerName != 0 && *prefs->mailServerName != 0;
  432.             DlgEnableItem(dlg, ok, enable);
  433.             DlgEnableItem(dlg, kTopicPopup, enable);
  434.             
  435.     }
  436.     
  437.     return noErr;
  438. }
  439.  
  440.  
  441.  
  442. /*----------------------------------------------------------------------------
  443.     ServerOptions
  444.  
  445.     Handles the server options preferences dialog.
  446.     
  447.     Entry:    prefs = pointer to new prefs.
  448.             dlg = pointer to dialog.
  449.             item = item number hit.
  450.             
  451.     Exit:    function result = error code.
  452. ----------------------------------------------------------------------------*/
  453.  
  454. static OSErr ServerOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  455. {
  456.     switch (item) {
  457.     
  458.         case kInit:
  459.         
  460.             DlgSetCheck(dlg, kBatchedGroupCmds, prefs->batchedGroupCmds);
  461.             DlgSetCheck(dlg, kUseXPAT, prefs->useXPAT);
  462.             DlgSetCheck(dlg, kNoNewConnection, prefs->noNewConnection);
  463.             DlgSetCheck(dlg, kNoModeReader, prefs->noModeReader);
  464.             break;
  465.             
  466.         case kTerm:
  467.             
  468.             prefs->batchedGroupCmds = DlgGetCheck(dlg, kBatchedGroupCmds);
  469.             prefs->useXPAT = DlgGetCheck(dlg, kUseXPAT);
  470.             prefs->noNewConnection = DlgGetCheck(dlg, kNoNewConnection);
  471.             prefs->noModeReader = DlgGetCheck(dlg, kNoModeReader);
  472.             break;
  473.             
  474.         case kBatchedGroupCmds:
  475.         case kUseXPAT:
  476.         case kNoNewConnection:
  477.         case kNoModeReader:
  478.         
  479.             DlgToggleCheck(dlg, item);
  480.             break;
  481.             
  482.     }
  483.     
  484.     return noErr;
  485. }
  486.  
  487.  
  488.  
  489. /*----------------------------------------------------------------------------
  490.     Personal
  491.  
  492.     Handles the personal info preferences dialog.
  493.     
  494.     Entry:    prefs = pointer to new prefs.
  495.             dlg = pointer to dialog.
  496.             item = item number hit.
  497.             
  498.     Exit:    function result = error code.
  499. ----------------------------------------------------------------------------*/
  500.  
  501. static OSErr Personal (TPrefRec *prefs, DialogPtr dlg, short item)
  502. {
  503.     switch (item) {
  504.     
  505.         case kInit:
  506.         
  507.             DlgSetCString(dlg, kFullName, prefs->fullName);
  508.             SetItemMaxLength(dlg, kFullName, 255);
  509.             DlgSetCString(dlg, kOrganization, prefs->organization);
  510.             SetItemMaxLength(dlg, kOrganization, 255);
  511.             DlgSetCString(dlg, kMailAddress, prefs->emailAddress);
  512.             SetItemUSAsciiNoBlank(dlg, kMailAddress);
  513.             SetItemMaxLength(dlg, kMailAddress, 255);
  514.             if (*prefs->fullName == 0) {
  515.                 SelectDialogItemText(dlg, kFullName, 0, 0);
  516.             } else if (*prefs->organization == 0) {
  517.                 SelectDialogItemText(dlg, kOrganization, 0, 0);
  518.             } else if (*prefs->emailAddress == 0) {
  519.                 SelectDialogItemText(dlg, kMailAddress, 0, 0);
  520.             } else {
  521.                 SelectDialogItemText(dlg, kFullName, 0, kMaxShort);
  522.             }
  523.             break;
  524.             
  525.         case kTerm:
  526.             
  527.             if (gItem != cancel && !StringIsValidEmailAddress(prefs->emailAddress)) {
  528.                 StopAlertNumber(kStrBadEmailAddress);
  529.                 gValid = false;
  530.                 return noErr;
  531.             }
  532.             DlgGetCString(dlg, kFullName, prefs->fullName);
  533.             DlgGetCString(dlg, kOrganization, prefs->organization);
  534.             break;
  535.             
  536.         case kMailAddress:
  537.         
  538.             DlgGetCString(dlg, kMailAddress, prefs->emailAddress);
  539.             DlgEnableItem(dlg, ok, *prefs->emailAddress != 0);
  540.             DlgEnableItem(dlg, kTopicPopup, *prefs->emailAddress != 0);
  541.             
  542.     }
  543.     
  544.     return noErr;
  545. }
  546.  
  547.  
  548.  
  549. /*----------------------------------------------------------------------------
  550.     Signature
  551.  
  552.     Handles the signature preferences dialog.
  553.     
  554.     Entry:    prefs = pointer to new prefs.
  555.             dlg = pointer to dialog.
  556.             item = item number hit.
  557.             
  558.     Exit:    function result = error code.
  559. ----------------------------------------------------------------------------*/
  560.  
  561. static OSErr Signature (TPrefRec *prefs, DialogPtr dlg, short item)
  562. {
  563.     short len;
  564.  
  565.     switch (item) {
  566.     
  567.         case kInit:
  568.         
  569.             DlgSetCheck(dlg, kAddSigBlankLine, prefs->addSigBlankLine);
  570.             DlgSetCheck(dlg, kAddSigSeparator, prefs->addSigSeparatorLine);
  571.             SetItemScrollingTextField(dlg, kSignatureEditText, 
  572.                 prefs->textFont, prefs->textSize, false);
  573.             DlgSetScrollingText(dlg, kSignatureEditText, prefs->signature,
  574.                 strlen(prefs->signature));
  575.             DlgSetScrollingTextSelection(dlg, kSignatureEditText, 0, 0);
  576.             SetItemMaxLength(dlg, kSignatureEditText, 4095);
  577.             break;
  578.             
  579.         case kTerm:
  580.             
  581.             prefs->addSigBlankLine = DlgGetCheck(dlg, kAddSigBlankLine);
  582.             prefs->addSigSeparatorLine = DlgGetCheck(dlg, kAddSigSeparator);
  583.             DlgGetScrollingText(dlg, kSignatureEditText, prefs->signature, &len);
  584.             prefs->signature[len] = 0;
  585.             break;
  586.             
  587.         case kAddSigBlankLine:
  588.         case kAddSigSeparator:
  589.         
  590.             DlgToggleCheck(dlg, item);
  591.             break;
  592.             
  593.     }
  594.     
  595.     return noErr;
  596. }
  597.  
  598.  
  599.  
  600. /*----------------------------------------------------------------------------
  601.     MessageOptions
  602.  
  603.     Handles the message options preferences dialog.
  604.     
  605.     Entry:    prefs = pointer to new prefs.
  606.             dlg = pointer to dialog.
  607.             item = item number hit.
  608.             
  609.     Exit:    function result = error code.
  610. ----------------------------------------------------------------------------*/
  611.  
  612. static OSErr MessageOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  613. {
  614.  
  615.     switch (item) {
  616.     
  617.         case kInit:
  618.         
  619.             DlgSetCheck(dlg, kMsgReplyPost, prefs->replyPost);
  620.             DlgSetCheck(dlg, kMsgReplyEmail, prefs->replyEmail);
  621.             DlgSetCheck(dlg, kMsgCopySelf, prefs->copySelf);
  622.             DlgSetCheck(dlg, kMsgShowMsgDetails, prefs->showMsgDetails);
  623.             DlgSetCheck(dlg, kMsgWrapOnSend, prefs->wrapOnSend);
  624.             DlgSetCheck(dlg, kMsgShowLabels, prefs->showLabelsUnderIcons);
  625.             DlgSetCheck(dlg, kMsgTabEnabled, prefs->tabEnabled);
  626.             DlgSetNumber(dlg, kMsgTabStops, prefs->tabStops);
  627.             SetItemNumeric(dlg, kMsgTabStops);
  628.             SetItemMaxLength(dlg, kMsgTabStops, 2);
  629.             SelectDialogItemText(dlg, kMsgTabStops, 0, kMaxShort);
  630.             DlgSetCString(dlg, kMsgQuoteString, prefs->quoteString);
  631.             SetItemMaxLength(dlg, kMsgQuoteString, 10);
  632.             break;
  633.             
  634.         case kTerm:
  635.             
  636.             prefs->replyPost = DlgGetCheck(dlg, kMsgReplyPost);
  637.             prefs->replyEmail = DlgGetCheck(dlg, kMsgReplyEmail);
  638.             prefs->copySelf = DlgGetCheck(dlg, kMsgCopySelf);
  639.             prefs->showMsgDetails = DlgGetCheck(dlg, kMsgShowMsgDetails);
  640.             prefs->wrapOnSend = DlgGetCheck(dlg, kMsgWrapOnSend);
  641.             prefs->showLabelsUnderIcons = DlgGetCheck(dlg, kMsgShowLabels);
  642.             prefs->tabEnabled = DlgGetCheck(dlg, kMsgTabEnabled);
  643.             prefs->tabStops = DlgGetNumber(dlg, kMsgTabStops);
  644.             DlgGetCString(dlg, kMsgQuoteString, prefs->quoteString);
  645.               break;
  646.             
  647.         case kMsgReplyPost:
  648.         case kMsgReplyEmail:
  649.         case kMsgCopySelf:
  650.         case kMsgShowMsgDetails:
  651.         case kMsgWrapOnSend:
  652.         case kMsgShowLabels:
  653.         case kMsgTabEnabled:
  654.         
  655.             DlgToggleCheck(dlg, item);
  656.             break;
  657.             
  658.     }
  659.     
  660.     return noErr;
  661. }
  662.  
  663.  
  664.  
  665. /*----------------------------------------------------------------------------
  666.     ExtraHeaderLines
  667.  
  668.     Handles the extra header lines preferences dialog.
  669.     
  670.     Entry:    prefs = pointer to new prefs.
  671.             dlg = pointer to dialog.
  672.             item = item number hit.
  673.             
  674.     Exit:    function result = error code.
  675. ----------------------------------------------------------------------------*/
  676.  
  677. static OSErr ExtraHeaderLines (TPrefRec *prefs, DialogPtr dlg, short item)
  678. {
  679.     short len;
  680.  
  681.     switch (item) {
  682.     
  683.         case kInit:
  684.         
  685.             SetItemScrollingTextField(dlg, kMsgExtraNewsHdrLines, 
  686.                 prefs->textFont, prefs->textSize, false);
  687.             DlgSetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines,
  688.                 strlen(prefs->extraNewsHdrLines));
  689.             SetItemMaxLength(dlg, kMsgExtraNewsHdrLines, 255);
  690.             SetItemScrollingTextField(dlg, kMsgExtraMailHdrLines, 
  691.                 prefs->textFont, prefs->textSize, false);
  692.             DlgSetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines,
  693.                 strlen(prefs->extraMailHdrLines));
  694.             SetItemMaxLength(dlg, kMsgExtraMailHdrLines, 255);
  695.             DlgSetScrollingTextSelection(dlg, kMsgExtraNewsHdrLines, 0, 0);
  696.             break;
  697.             
  698.         case kTerm:
  699.             
  700.             DlgGetScrollingText(dlg, kMsgExtraNewsHdrLines, prefs->extraNewsHdrLines, &len);
  701.             prefs->extraNewsHdrLines[len] = 0;
  702.             DlgGetScrollingText(dlg, kMsgExtraMailHdrLines, prefs->extraMailHdrLines, &len);
  703.             prefs->extraMailHdrLines[len] = 0;
  704.               break;
  705.             
  706.     }
  707.     
  708.     return noErr;
  709. }
  710.  
  711.  
  712.  
  713. /*----------------------------------------------------------------------------
  714.     Remote
  715.  
  716.     Handles the remote host info preferences dialog.
  717.     
  718.     Entry:    prefs = pointer to new prefs.
  719.             dlg = pointer to dialog.
  720.             item = item number hit.
  721.             
  722.     Exit:    function result = error code.
  723. ----------------------------------------------------------------------------*/
  724.  
  725. static OSErr Remote (TPrefRec *prefs, DialogPtr dlg, short item)
  726. {
  727.     CStr255 tempStr;
  728.     short len;
  729.  
  730.     switch (item) {
  731.     
  732.         case kInit:
  733.         
  734.             DlgSetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  735.             SetItemHostAddress(dlg, kRemoteHostAddr);
  736.             SetItemMaxLength(dlg, kRemoteHostAddr, 255);
  737.             DlgSetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  738.             SetItemUSAsciiNoBlank(dlg, kRemoteLogin);
  739.             SetItemMaxLength(dlg, kRemoteLogin, 255);
  740.             len = strlen(prefs->ftpNewsrcPassword);
  741.             memset(tempStr, '•', len);
  742.             tempStr[len] = 0;
  743.             DlgSetCString(dlg, kRemotePassword, tempStr);
  744.             SetItemPassword(dlg, kRemotePassword, prefs->ftpNewsrcPassword);
  745.             SetItemMaxLength(dlg, kRemotePassword, 31);
  746.             DlgSetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  747.             SetItemMaxLength(dlg, kRemotePath, 31);
  748.             DlgSetCheck(dlg, kAutoGetPut, prefs->autoFetchNewsrc);
  749.             DlgSetCheck(dlg, kSavePassword, prefs->saveFtpNewsrcPassword);
  750.             if (*prefs->ftpNewsrcHost == 0) {
  751.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, 0);
  752.             } else if (*prefs->ftpNewsrcUsername == 0) {
  753.                 SelectDialogItemText(dlg, kRemoteLogin, 0, 0);
  754.             } else if (*prefs->ftpNewsrcPassword == 0) {
  755.                 SelectDialogItemText(dlg, kRemotePassword, 0, 0);
  756.             } else if (*prefs->ftpNewsrcPath == 0) {
  757.                 SelectDialogItemText(dlg, kRemotePath, 0, 0);
  758.             } else {
  759.                 SelectDialogItemText(dlg, kRemoteHostAddr, 0, kMaxShort);
  760.             }
  761.             break;
  762.             
  763.         case kTerm:
  764.             
  765.             DlgGetCString(dlg, kRemoteHostAddr, prefs->ftpNewsrcHost);
  766.             DlgGetCString(dlg, kRemoteLogin, prefs->ftpNewsrcUsername);
  767.             DlgGetCString(dlg, kRemotePath, prefs->ftpNewsrcPath);
  768.             prefs->autoFetchNewsrc = DlgGetCheck(dlg, kAutoGetPut);
  769.             prefs->saveFtpNewsrcPassword = DlgGetCheck(dlg, kSavePassword);
  770.             break;
  771.         
  772.         case kSavePassword:
  773.         case kAutoGetPut:
  774.         
  775.             DlgToggleCheck(dlg, item);
  776.             break;
  777.             
  778.     }
  779.     
  780.     return noErr;
  781. }
  782.  
  783.  
  784.  
  785. /*----------------------------------------------------------------------------
  786.     DrawFontSample
  787.     
  788.     A user item procedure to draw the font samples.
  789.     
  790.     Entry:    dlg = pointer to dialog.
  791.             item = item number.
  792. ----------------------------------------------------------------------------*/
  793.  
  794. static pascal void DrawFontSample (DialogPtr dlg, short item)
  795. {
  796.     short itemType;
  797.     Rect box;
  798.     Handle itemHandle;
  799.     Str255 text;
  800.     short fontID, fontSize;
  801.     TextStyle savedStyle;
  802.  
  803.     DlgGrayBorderItem(dlg, item);
  804.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  805.     if (gScreenFontsTopic) {
  806.         if (item == kListSample) {
  807.             GetPString(kStrGroupSubjectSample, text);
  808.             fontID = gListFontID;
  809.             fontSize = gListFontSize;
  810.         } else {
  811.             GetPString(kStrArtMsgSample, text);
  812.             fontID = gTextFontID;
  813.             fontSize = gTextFontSize;
  814.         }
  815.     } else {
  816.         GetPString(kStrPrintingSample, text);
  817.         fontID = gPrintingFontID;
  818.         fontSize = gPrintingFontSize;
  819.     }
  820.     GetPortTextStyle(&savedStyle);
  821.     TextFont(fontID);
  822.     TextSize(fontSize);
  823.     InsetRect(&box, 2, 2);
  824.     TETextBox(text + 1, *text, &box, teFlushDefault);
  825.     SetPortTextStyle(&savedStyle);
  826. }
  827.  
  828.  
  829.  
  830. /*----------------------------------------------------------------------------
  831.     RedrawSample
  832.  
  833.     Force one of the sample text items to be redrawn.
  834.     
  835.     Entry:    dlg = pointer to dialog.
  836.             item = item number.
  837. ----------------------------------------------------------------------------*/
  838.  
  839. static void RedrawSample (DialogPtr dlg, short item)
  840. {
  841.     short itemType;
  842.     Handle itemHandle;
  843.     Rect box;
  844.     
  845.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  846.     InsetRect(&box, 2, 2);
  847.     EraseRect(&box);
  848.     InvalRect(&box);
  849. }
  850.  
  851.  
  852.  
  853. /*----------------------------------------------------------------------------
  854.     SetNewFont
  855.  
  856.     Set a new font in the font/size dialog.
  857.     
  858.     Entry:    dlg = pointer to dialog.
  859.             listFont = true if list font, false if text font.
  860.             fontNum = new font number.
  861. ----------------------------------------------------------------------------*/
  862.  
  863. static void SetNewFont (DialogPtr dlg, Boolean listFont, short fontNum)
  864. {
  865.     short numItems, i;
  866.     Str255 itemStr, fontName;
  867.     ControlHandle ctl;
  868.     long size;
  869.  
  870.     /* Select the right font in the font popup menu. */
  871.     
  872.     ctl = DlgGetControl(dlg, 
  873.         gScreenFontsTopic ? (listFont ? kListFontPopup : kTextFontPopup) : kPrintingFontPopup);
  874.     GetFontName(fontNum, fontName);
  875.     SetPopupValue(ctl, fontName, false);
  876.     
  877.     /* Adjust the size popup so the nice sizes are outlined. */
  878.  
  879.     ctl = DlgGetControl(dlg, 
  880.         gScreenFontsTopic ? (listFont ? kListSizePopup : kTextSizePopup) : kPrintingSizePopup);
  881.     numItems = GetControlMaximum(ctl);
  882.     for (i = 1; i <= numItems; i++) {
  883.         GetPopupPString(ctl, i, itemStr);
  884.         StringToNum(itemStr, &size);
  885.         if (RealFont(fontNum, (short)size)) {
  886.             SetPopupItemStyle(ctl, i, outline);
  887.         } else {
  888.             SetPopupItemStyle(ctl, i, 0);
  889.         }
  890.     }
  891.  
  892.     /* Force the sample text to be redrawn */
  893.     
  894.     RedrawSample(dlg, 
  895.         gScreenFontsTopic ? (listFont ? kListSample : kTextSample) : kPrintingSample);
  896. }
  897.  
  898.  
  899.  
  900. /*----------------------------------------------------------------------------
  901.     FontIDFromPopup
  902.  
  903.     Get the font ID corresponding the currently selected font in a popup menu.
  904.     
  905.     Entry:    dlg = pointer to dialog.
  906.             item = item number of popup menu.
  907. ----------------------------------------------------------------------------*/
  908.  
  909. static short FontIDFromPopup (DialogPtr dlg, short item)
  910. {
  911.     ControlHandle ctl;
  912.     short fontNum;
  913.     Str255 fontName;
  914.  
  915.     ctl = DlgGetControl(dlg, item);
  916.     GetPopupPString(ctl, kCurrentPopupItem, fontName);
  917.     GetFontNumber(fontName, &fontNum);
  918.     return fontNum;
  919. }
  920.  
  921.  
  922.  
  923. /*----------------------------------------------------------------------------
  924.     ScreenFonts
  925.  
  926.     Handles the screen fonts preferences dialog.
  927.     
  928.     Entry:    prefs = pointer to new prefs.
  929.             dlg = pointer to dialog.
  930.             item = item number hit.
  931.             
  932.     Exit:    function result = error code.
  933. ----------------------------------------------------------------------------*/
  934.  
  935. static OSErr ScreenFonts (TPrefRec *prefs, DialogPtr dlg, short item)
  936. {
  937.     Str255 tempStr;
  938.     long num;
  939.  
  940.     switch (item) {
  941.     
  942.         case kInit:
  943.         
  944.             gScreenFontsTopic = true;
  945.             GetFontNumber(prefs->listFont, &gListFontID);
  946.             gListFontSize = prefs->listSize;
  947.             SetNewFont(dlg, true, gListFontID);
  948.             DlgSetNumber(dlg, kListSizeBox, gListFontSize);
  949.             SetItemNumeric(dlg, kListSizeBox);
  950.             SetItemMaxLength(dlg, kListSizeBox, 2);
  951.             SelectDialogItemText(dlg, kListSizeBox, 0, kMaxShort);
  952.             SetItemPopupTypeinItem(dlg, kListSizePopup, kListSizeBox);
  953.             
  954.             GetFontNumber(prefs->textFont, &gTextFontID);
  955.             gTextFontSize = prefs->textSize;
  956.             SetNewFont(dlg, false, gTextFontID);
  957.             DlgSetNumber(dlg, kTextSizeBox, gTextFontSize);
  958.             SetItemNumeric(dlg, kTextSizeBox);
  959.             SetItemMaxLength(dlg, kTextSizeBox, 2);
  960.             SetItemPopupTypeinItem(dlg, kTextSizePopup, kTextSizeBox);
  961.             
  962.               DlgSetUserItem(dlg, kListSample, gDrawFontSampleUPP);
  963.               DlgSetUserItem(dlg, kTextSample, gDrawFontSampleUPP);
  964.               DlgSetUserItem(dlg, kListVertLine, gDlgGrayBorderItemUPP);
  965.             break;
  966.             
  967.         case kTerm:
  968.             
  969.               GetFontName(gListFontID, prefs->listFont);
  970.               GetFontName(gTextFontID, prefs->textFont);
  971.               prefs->listSize = gListFontSize;
  972.               prefs->textSize = gTextFontSize;
  973.             break;
  974.             
  975.         case kListFontPopup:
  976.         
  977.               gListFontID = FontIDFromPopup(dlg, item);
  978.               SetNewFont(dlg, true, gListFontID);
  979.             break;
  980.             
  981.         case kTextFontPopup:
  982.         
  983.               gTextFontID = FontIDFromPopup(dlg, item);
  984.               SetNewFont(dlg, false, gTextFontID);
  985.             break;            
  986.           
  987.         case kListSizePopup:
  988.         case kListSizeBox:
  989.         
  990.               DlgGetPString(dlg, kListSizeBox, tempStr);
  991.               StringToNum(tempStr, &num);
  992.               if (num != 0 && num != gListFontSize) {
  993.                   gListFontSize = num;
  994.                   RedrawSample(dlg, kListSample);
  995.               }
  996.             break;
  997.           
  998.         case kTextSizePopup:
  999.         case kTextSizeBox:
  1000.         
  1001.               DlgGetPString(dlg, kTextSizeBox, tempStr);
  1002.               StringToNum(tempStr, &num);
  1003.               if (num != 0 && num != gTextFontSize) {
  1004.                   gTextFontSize = num;
  1005.                   RedrawSample(dlg, kTextSample);
  1006.               }
  1007.             break;
  1008.             
  1009.     }
  1010.     
  1011.     return noErr;
  1012. }
  1013.  
  1014.  
  1015.  
  1016. /*----------------------------------------------------------------------------
  1017.     PrintingFont
  1018.  
  1019.     Handles the printing font preferences dialog.
  1020.     
  1021.     Entry:    prefs = pointer to new prefs.
  1022.             dlg = pointer to dialog.
  1023.             item = item number hit.
  1024.             
  1025.     Exit:    function result = error code.
  1026. ----------------------------------------------------------------------------*/
  1027.  
  1028. static OSErr PrintingFont (TPrefRec *prefs, DialogPtr dlg, short item)
  1029. {
  1030.     Str255 tempStr;
  1031.     long num;
  1032.  
  1033.     switch (item) {
  1034.     
  1035.         case kInit:
  1036.         
  1037.             gScreenFontsTopic = false;
  1038.             GetFontNumber(prefs->printingFont, &gPrintingFontID);
  1039.             gPrintingFontSize = prefs->printingSize;
  1040.             SetNewFont(dlg, true, gPrintingFontID);
  1041.             DlgSetNumber(dlg, kPrintingSizeBox, gPrintingFontSize);
  1042.             SetItemNumeric(dlg, kPrintingSizeBox);
  1043.             SetItemMaxLength(dlg, kPrintingSizeBox, 2);
  1044.             SelectDialogItemText(dlg, kPrintingSizeBox, 0, kMaxShort);
  1045.             SetItemPopupTypeinItem(dlg, kPrintingSizePopup, kPrintingSizeBox);
  1046.               DlgSetUserItem(dlg, kPrintingSample, gDrawFontSampleUPP);
  1047.             break;
  1048.             
  1049.         case kTerm:
  1050.             
  1051.               GetFontName(gPrintingFontID, prefs->printingFont);
  1052.               prefs->printingSize = gPrintingFontSize;
  1053.             break;
  1054.             
  1055.         case kPrintingFontPopup:
  1056.         
  1057.               gPrintingFontID = FontIDFromPopup(dlg, item);
  1058.               SetNewFont(dlg, true, gPrintingFontID);
  1059.             break;
  1060.           
  1061.         case kPrintingSizePopup:
  1062.         case kPrintingSizeBox:
  1063.         
  1064.               DlgGetPString(dlg, kPrintingSizeBox, tempStr);
  1065.               StringToNum(tempStr, &num);
  1066.               if (num != 0 && num != gPrintingFontSize) {
  1067.                   gPrintingFontSize = num;
  1068.                   RedrawSample(dlg, kPrintingSample);
  1069.               }
  1070.             break;
  1071.             
  1072.     }
  1073.     
  1074.     return noErr;
  1075. }
  1076.  
  1077.  
  1078.  
  1079. /*----------------------------------------------------------------------------
  1080.     SavedUGL
  1081.  
  1082.     Handles the saved user group lists preferences dialog.
  1083.     
  1084.     Entry:    prefs = pointer to new prefs.
  1085.             dlg = pointer to dialog.
  1086.             item = item number hit.
  1087.             
  1088.     Exit:    function result = error code.
  1089. ----------------------------------------------------------------------------*/
  1090.  
  1091. static OSErr SavedUGL (TPrefRec *prefs, DialogPtr dlg, short item)
  1092. {
  1093.     StandardFileReply reply;
  1094.     long dirID;
  1095.     Str31 name;
  1096.     OSErr err = noErr;
  1097.     CInfoPBRec pb;
  1098.     Boolean valid;
  1099.     AliasHandle alias;
  1100.  
  1101.     switch (item) {
  1102.     
  1103.         case kInit:
  1104.  
  1105.             DlgSetCheck(dlg, kSavedUGLDirCheckBox, prefs->savedUGLDefaultFolder);
  1106.               DlgSetUserItem(dlg, kSavedUGLDirBorder, gDlgGrayBorderItemUPP);            
  1107.             ValidateSavedFolderAlias(prefs->savedUGLDefaultFolderAlias,
  1108.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1109.               if (valid) {
  1110.                 pb.dirInfo.ioNamePtr = name;
  1111.                 pb.dirInfo.ioFDirIndex = -1;
  1112.                 PBGetCatInfo(&pb, false);
  1113.             } else {
  1114.                *name = 0;
  1115.             }
  1116.             DlgSetPString(dlg, kSavedUGLDirName, name);
  1117.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1118.             DlgSetCheck(dlg, kSavedUGLAutoSaveOnQuit, prefs->autoSaveOnQuit);
  1119.                 
  1120.             break;
  1121.             
  1122.         case kTerm:
  1123.         
  1124.             prefs->autoSaveOnQuit = DlgGetCheck(dlg, kSavedUGLAutoSaveOnQuit);
  1125.             break;
  1126.             
  1127.         case kSavedUGLDirCheckBox:
  1128.         
  1129.             DlgToggleCheck(dlg, item);
  1130.             prefs->savedUGLDefaultFolder = DlgGetCheck(dlg, item);
  1131.             DlgEnableItem(dlg, kSavedUGLDirButton, prefs->savedUGLDefaultFolder);
  1132.             break;
  1133.             
  1134.         case kSavedUGLDirButton:
  1135.         
  1136.             MyStandardGetDirectory(&reply, &dirID);
  1137.             if (!reply.sfGood) break;
  1138.             err = NewAlias(nil, &reply.sfFile, &alias);
  1139.             if (err == noErr) {
  1140.                 MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  1141.                 prefs->savedUGLDefaultFolderAlias = alias;
  1142.             }
  1143.             DlgSetPString(dlg, kSavedUGLDirName, reply.sfFile.name);
  1144.             break;
  1145.             
  1146.         case kSavedUGLAutoSaveOnQuit:
  1147.         
  1148.             DlgToggleCheck(dlg, item);
  1149.             break;
  1150.             
  1151.     }
  1152.     
  1153.     return noErr;
  1154. }
  1155.  
  1156.  
  1157.  
  1158. /*----------------------------------------------------------------------------
  1159.     InvisibleFilesFilter
  1160.  
  1161.     A standard file dialog filter to filter out invisible files.
  1162.     
  1163.     Entry:    pb = pointer to file info param block.
  1164.             myDataPtr = pointer to private data (not used).
  1165.             
  1166.     Exit:    function result = true if file is invisible.
  1167. ----------------------------------------------------------------------------*/
  1168.  
  1169. static pascal Boolean InvisibleFilesFilter (CInfoPBPtr pb, void *myDataPtr)
  1170. {
  1171.     return (pb->hFileInfo.ioFlFndrInfo.fdFlags & fInvisible) != 0;
  1172. }
  1173.  
  1174.  
  1175.  
  1176. /*----------------------------------------------------------------------------
  1177.     SavedArt
  1178.  
  1179.     Handles the saved articles preferences dialog.
  1180.     
  1181.     Entry:    prefs = pointer to new prefs.
  1182.             dlg = pointer to dialog.
  1183.             item = item number hit.
  1184.             
  1185.     Exit:    function result = error code.
  1186. ----------------------------------------------------------------------------*/
  1187.  
  1188. static OSErr SavedArt (TPrefRec *prefs, DialogPtr dlg, short item)
  1189. {
  1190.     StandardFileReply reply;
  1191.     FInfo fInfo;
  1192.     long dirID;
  1193.     Str31 name;
  1194.     OSErr err = noErr;
  1195.     CInfoPBRec pb;
  1196.     Boolean valid;
  1197.     AliasHandle alias;
  1198.  
  1199.     switch (item) {
  1200.     
  1201.         case kInit:
  1202.  
  1203.               DlgSetUserItem(dlg, kSavedArtAppBorder, gDlgGrayBorderItemUPP);
  1204.               err = FindAppNameFromSig(prefs->savedArtCreator, name);
  1205.               if (err == noErr) {
  1206.                   DlgSetPString(dlg, kSavedArtAppName, name);
  1207.                   CopyPascalString(prefs->savedArtAppName, name);
  1208.               } else {
  1209.                 DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1210.             }
  1211.             DlgSetCheck(dlg, kSavedArtDirCheckBox, prefs->savedArtDefaultFolder);
  1212.               DlgSetUserItem(dlg, kSavedArtDirBorder, gDlgGrayBorderItemUPP);            
  1213.             ValidateSavedFolderAlias(prefs->savedArtDefaultFolderAlias,
  1214.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1215.               if (valid) {
  1216.                 pb.dirInfo.ioNamePtr = name;
  1217.                 pb.dirInfo.ioFDirIndex = -1;
  1218.                 PBGetCatInfo(&pb, false);
  1219.             } else {
  1220.                *name = 0;
  1221.             }
  1222.             DlgSetPString(dlg, kSavedArtDirName, name);
  1223.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1224.             DlgSetCheck(dlg, kSavedArtSepFiles, prefs->saveThreadsToSeparateFiles);
  1225.             DlgSetCheck(dlg, kSavedArtAutoAppend, prefs->appendIfFileAlreadyExists);
  1226.             DlgSetCheck(dlg, kSavedArtSaveEncoded, prefs->saveEncodedText);
  1227.                 
  1228.             break;
  1229.             
  1230.         case kTerm:
  1231.         
  1232.             prefs->saveThreadsToSeparateFiles = DlgGetCheck(dlg, kSavedArtSepFiles);
  1233.             prefs->appendIfFileAlreadyExists = DlgGetCheck(dlg, kSavedArtAutoAppend);
  1234.             prefs->saveEncodedText = DlgGetCheck(dlg, kSavedArtSaveEncoded);
  1235.             break;
  1236.             
  1237.         case kSavedArtAppButton:
  1238.         
  1239.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1240.             if (!reply.sfGood) break;
  1241.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1242.             prefs->savedArtCreator = fInfo.fdCreator;
  1243.             CopyPascalString(prefs->savedArtAppName, reply.sfFile.name);
  1244.             DlgSetPString(dlg, kSavedArtAppName, prefs->savedArtAppName);
  1245.             break;
  1246.             
  1247.         case kSavedArtDirCheckBox:
  1248.         
  1249.             DlgToggleCheck(dlg, item);
  1250.             prefs->savedArtDefaultFolder = DlgGetCheck(dlg, item);
  1251.             DlgEnableItem(dlg, kSavedArtDirButton, prefs->savedArtDefaultFolder);
  1252.             break;
  1253.             
  1254.         case kSavedArtDirButton:
  1255.         
  1256.             MyStandardGetDirectory(&reply, &dirID);
  1257.             if (!reply.sfGood) break;
  1258.             err = NewAlias(nil, &reply.sfFile, &alias);
  1259.             if (err == noErr) {
  1260.                 MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  1261.                 prefs->savedArtDefaultFolderAlias = alias;
  1262.             }
  1263.             DlgSetPString(dlg, kSavedArtDirName, reply.sfFile.name);
  1264.             break;
  1265.             
  1266.         case kSavedArtSepFiles:
  1267.         case kSavedArtAutoAppend:
  1268.         case kSavedArtSaveEncoded:
  1269.         
  1270.             DlgToggleCheck(dlg, item);
  1271.             break;
  1272.             
  1273.     }
  1274.     
  1275.     return noErr;
  1276. }
  1277.  
  1278.  
  1279.  
  1280. /*----------------------------------------------------------------------------
  1281.     SavedMsg
  1282.  
  1283.     Handles the saved messages preferences dialog.
  1284.     
  1285.     Entry:    prefs = pointer to new prefs.
  1286.             dlg = pointer to dialog.
  1287.             item = item number hit.
  1288.             
  1289.     Exit:    function result = error code.
  1290. ----------------------------------------------------------------------------*/
  1291.  
  1292. static OSErr SavedMsg (TPrefRec *prefs, DialogPtr dlg, short item)
  1293. {
  1294.     StandardFileReply reply;
  1295.     long dirID;
  1296.     Str31 name;
  1297.     OSErr err = noErr;
  1298.     CInfoPBRec pb;
  1299.     Boolean valid;
  1300.     AliasHandle alias;
  1301.  
  1302.     switch (item) {
  1303.     
  1304.         case kInit:
  1305.  
  1306.             DlgSetCheck(dlg, kSavedMsgDirCheckBox, prefs->savedMsgDefaultFolder);
  1307.               DlgSetUserItem(dlg, kSavedMsgDirBorder, gDlgGrayBorderItemUPP);            
  1308.             ValidateSavedFolderAlias(prefs->savedMsgDefaultFolderAlias,
  1309.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1310.               if (valid) {
  1311.                 pb.dirInfo.ioNamePtr = name;
  1312.                 pb.dirInfo.ioFDirIndex = -1;
  1313.                 PBGetCatInfo(&pb, false);
  1314.             } else {
  1315.                 *name = 0;
  1316.             }
  1317.             DlgSetPString(dlg, kSavedMsgDirName, name);
  1318.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1319.             DlgSetCheck(dlg, kSavedMsgDelAfterSend, prefs->savedMsgDelAfterSend);
  1320.                 
  1321.             break;
  1322.             
  1323.         case kTerm:
  1324.         
  1325.             break;
  1326.             
  1327.         case kSavedMsgDirCheckBox:
  1328.         
  1329.             DlgToggleCheck(dlg, item);
  1330.             prefs->savedMsgDefaultFolder = DlgGetCheck(dlg, item);
  1331.             DlgEnableItem(dlg, kSavedMsgDirButton, prefs->savedMsgDefaultFolder);
  1332.             break;
  1333.             
  1334.         case kSavedMsgDirButton:
  1335.         
  1336.             MyStandardGetDirectory(&reply, &dirID);
  1337.             if (!reply.sfGood) break;
  1338.             err = NewAlias(nil, &reply.sfFile, &alias);
  1339.             if (err == noErr) {
  1340.                 MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  1341.                 prefs->savedMsgDefaultFolderAlias = alias;
  1342.             }
  1343.             DlgSetPString(dlg, kSavedMsgDirName, reply.sfFile.name);
  1344.             break;
  1345.             
  1346.         case kSavedMsgDelAfterSend:
  1347.         
  1348.             DlgToggleCheck(dlg, item);
  1349.             prefs->savedMsgDelAfterSend = DlgGetCheck(dlg, item);
  1350.             break;
  1351.             
  1352.     }
  1353.     
  1354.     return noErr;
  1355. }
  1356.  
  1357.  
  1358.  
  1359. /*----------------------------------------------------------------------------
  1360.     DrawURLItem
  1361.     
  1362.     Draw a URL helper list item.
  1363.     
  1364.     Entry:    theList = URL helper list ref = gURLList.
  1365.             offset = offset of C-format string to draw in gURLListStrings.
  1366.             *itemRect = item rectangle.
  1367. ----------------------------------------------------------------------------*/
  1368.  
  1369. static void DrawURLItem (BigListRef theList, long offset, Rect *itemRect)
  1370. {
  1371.     Str255 str;
  1372.     FontInfo fontInfo;
  1373.     
  1374.     strcpy((char*)str, *gURLListStrings+offset);
  1375.     c2pstr((char*)str);
  1376.     TruncString(itemRect->right - itemRect->left, str, smTruncEnd);
  1377.     GetFontInfo(&fontInfo);
  1378.     MoveTo(itemRect->left, itemRect->top + fontInfo.ascent);
  1379.     DrawString(str);
  1380. }
  1381.  
  1382.  
  1383.  
  1384. /*----------------------------------------------------------------------------
  1385.     DrawURLList
  1386.     
  1387.     A user item procedure to draw the URL helper list.
  1388.     
  1389.     Entry:    dlg = pointer to dialog.
  1390.             item = item number.
  1391. ----------------------------------------------------------------------------*/
  1392.  
  1393. static pascal void DrawURLList (DialogPtr dlg, short item)
  1394. {
  1395.     short itemType;
  1396.     Rect box;
  1397.     Handle itemHandle;
  1398.  
  1399.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  1400.     FrameRect(&box);
  1401.     BigLGetViewRect(gURLList, &box);
  1402.     box.right -= 15;
  1403.     EraseRect(&box);
  1404.     BigLUpdate(gURLList);
  1405. }
  1406.  
  1407.  
  1408.  
  1409. /*----------------------------------------------------------------------------
  1410.     SetURLListItemString
  1411.  
  1412.     Set the string displayed for an item in the URL helper list.
  1413.     
  1414.     Entry:    prefs = pointer to new prefs.
  1415.             listItem = item number.
  1416.     
  1417.     Exit:    function result = error code.
  1418. ----------------------------------------------------------------------------*/
  1419.  
  1420. static OSErr SetURLListItemString (TPrefRec *prefs, long listItem)
  1421. {
  1422.     TURLHelperInfo helperInfo;
  1423.     char appName[32];
  1424.     CStr255 str;
  1425.     long len, offset;
  1426.     OSErr err = noErr;
  1427.     
  1428.     helperInfo = (*prefs->urlHelpers)[listItem];
  1429.     *appName = 0;
  1430.     if (helperInfo.sig != 0) FindAppNameFromSig(helperInfo.sig, (StringPtr)appName);
  1431.     p2cstr((StringPtr)appName);
  1432.     sprintf(str, "%s — %s", helperInfo.schemeName, appName);
  1433.     len = strlen(str) + 1;
  1434.     offset = MyGetHandleSize(gURLListStrings);
  1435.     err = MySetHandleSize(gURLListStrings, offset+len);
  1436.     if (err != noErr) return err;
  1437.     BlockMoveData(str, *gURLListStrings+offset, len);
  1438.     BigLSetData(gURLList, listItem, offset);
  1439.     return noErr;
  1440. }
  1441.  
  1442.  
  1443.  
  1444. /*----------------------------------------------------------------------------
  1445.     SetNewURLHelper
  1446.  
  1447.     Set a new URL helper.
  1448.     
  1449.     Entry:    prefs = pointer to new prefs.
  1450.     
  1451.     Exit:    function result = error code.
  1452. ----------------------------------------------------------------------------*/
  1453.  
  1454. static OSErr SetNewURLHelper (TPrefRec *prefs)
  1455. {
  1456.     TURLHelperInfo *p;
  1457.     long listItem;
  1458.     StandardFileReply reply;
  1459.     OSErr err = noErr;
  1460.  
  1461.     listItem = BigLGetFirstSelectedItem(gURLList);
  1462.     if (listItem < 0) return noErr;
  1463.     MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1464.     if (!reply.sfGood) return noErr;
  1465.     if (!ValidHelper(&reply.sfFile)) return noErr;
  1466.     MyHLock(prefs->urlHelpers);
  1467.     p = &(*prefs->urlHelpers)[listItem];
  1468.     if (ValidURLHelper(&reply.sfFile, p)) {
  1469.         err = SetURLListItemString(prefs, listItem);
  1470.     }
  1471.     MyHUnlock(prefs->urlHelpers);
  1472.     return err;
  1473. }
  1474.  
  1475.  
  1476.  
  1477. /*----------------------------------------------------------------------------
  1478.     AdjustURLButtons
  1479.  
  1480.     Adjust (enable/disable) the Change, Delete, and Add buttons in the URL
  1481.     helper programs topic.
  1482.     
  1483.     Entry:    dlg = pointer to dialog.
  1484. ----------------------------------------------------------------------------*/
  1485.  
  1486. static void AdjustURLButtons (DialogPtr dlg)
  1487. {
  1488.     Boolean itemSelected;
  1489.     TURLSchemeName schemeName;
  1490.     
  1491.     itemSelected = BigLListHasSelectedItem(gURLList);
  1492.     DlgEnableItem(dlg, kURLChangeButton, itemSelected);
  1493.     DlgEnableItem(dlg, kURLDeleteButton, itemSelected);
  1494.     DlgGetCString(dlg, kURLNewScheme, schemeName);
  1495.     DlgEnableItem(dlg, kURLAddButton, *schemeName != 0);
  1496. }
  1497.  
  1498.  
  1499.  
  1500. /*----------------------------------------------------------------------------
  1501.     CompareURLHelperInfo
  1502.  
  1503.     Compare two URL helper program info records.
  1504.     
  1505.     Entry:    a = pointer to first helper program info record.
  1506.             b = pointer to second helper program info record.
  1507.             
  1508.     Exit:    function result = 
  1509.                 -1 if a->schemeName < b->schemName
  1510.                 0  if a->schemeName = b->schemName
  1511.                 +1 if a->schemeName > b->schemName
  1512. ----------------------------------------------------------------------------*/
  1513.  
  1514. static OSErr CompareURLHelperInfo (TURLHelperInfo *a, TURLHelperInfo *b, short *result)
  1515. {
  1516.     *result = MyStrCmp(a->schemeName, b->schemeName);
  1517.     return noErr;
  1518. }
  1519.  
  1520.  
  1521.  
  1522. /*----------------------------------------------------------------------------
  1523.     URLScrollIntoView
  1524.     
  1525.     Scroll the selected item into view in the URL topic.
  1526. ----------------------------------------------------------------------------*/
  1527.  
  1528. static void URLScrollIntoView (void)
  1529. {
  1530.     long listItem;
  1531.     
  1532.     listItem = BigLGetFirstSelectedItem(gURLList);
  1533.     if (listItem < 0) return;
  1534.     BigLScrollItemIntoView(gURLList, listItem, kBigLScrollToTop, kBigLScrollToBottom);
  1535. }
  1536.  
  1537.  
  1538.  
  1539. /*----------------------------------------------------------------------------
  1540.     URLHelpersFilter
  1541.     
  1542.     Filter proc for the URL Helper Programs topic.
  1543.         
  1544.     Entry:    dlg = pointer to dialog.
  1545.             ev = pointer to event record.
  1546.             
  1547.     Exit:    function result = true if event handled and item hit.
  1548.             *itemHit = item number of item hit.
  1549.             ev = pointer to possibly modified event record.
  1550.             
  1551.     This dialog filter handles arrow keys and paging keys.
  1552. ----------------------------------------------------------------------------*/
  1553.  
  1554. static pascal Boolean URLHelpersFilter (DialogPtr dlg, EventRecord *ev, 
  1555.     short *itemHit)
  1556. {
  1557.     if (ev->what == keyDown || ev->what == autoKey) {
  1558.         if (BigLKey(gURLList, ev->message & charCodeMask, 0)) {
  1559.             AdjustURLButtons(dlg);
  1560.             ev->what = nullEvent;
  1561.             return false;
  1562.         }
  1563.     }
  1564.     return DialogFilter(dlg, ev, itemHit);
  1565. }
  1566.  
  1567.  
  1568.  
  1569. /*----------------------------------------------------------------------------
  1570.     URLHelpers
  1571.  
  1572.     Handles the URL helper programs preferences dialog.
  1573.     
  1574.     Entry:    prefs = pointer to new prefs.
  1575.             dlg = pointer to dialog.
  1576.             item = item number hit.
  1577.             
  1578.     Exit:    function result = error code.
  1579. ----------------------------------------------------------------------------*/
  1580.  
  1581. static OSErr URLHelpers (TPrefRec *prefs, DialogPtr dlg, short item)
  1582. {
  1583.     short itemType;
  1584.     Rect box;
  1585.     Handle itemHandle;
  1586.     Point where;
  1587.     TURLHelperInfo *p;
  1588.     long numHelpers, listItem;
  1589.     CStr255 fmt, msg;
  1590.     long len;
  1591.     TURLSchemeName schemeName;
  1592.     char *c;
  1593.     short cmp;
  1594.     TURLHelperInfo newHelper;
  1595.     OSErr err = noErr;
  1596.     StandardFileReply reply;
  1597.     Boolean doubleClick, savedHiliteState;
  1598.  
  1599.     switch (item) {
  1600.     
  1601.         case kInit:
  1602.             
  1603.             gURLList = nil;
  1604.             gURLListStrings = nil;
  1605.             GetDialogItem(dlg, kURLList, &itemType, &itemHandle, &box);
  1606.             FrameRect(&box);
  1607.             InsetRect(&box, 1, 1);
  1608.             numHelpers = 0;
  1609.             for (p = *prefs->urlHelpers; *p->schemeName != 0; p++) numHelpers++;
  1610.             savedHiliteState = ((WindowPeek)dlg)->hilited;
  1611.             ((WindowPeek)dlg)->hilited = true;
  1612.             err = BigLNew(&box, dlg, 0, true, DrawURLItem, &gURLList);
  1613.             ((WindowPeek)dlg)->hilited = savedHiliteState;
  1614.             if (err != noErr) goto exit;
  1615.             err = MyNewHandle(0, &gURLListStrings);
  1616.             if (err != noErr) goto exit;
  1617.             MyHLock(prefs->urlHelpers);
  1618.             FastQSort(*prefs->urlHelpers, numHelpers, sizeof(TURLHelperInfo), 
  1619.                 (SortCmpFunction)CompareURLHelperInfo);
  1620.             MyHUnlock(prefs->urlHelpers); 
  1621.             for (listItem = 0; listItem < numHelpers; listItem++) {
  1622.                 err = BigLAddItems(gURLList, listItem, 1);
  1623.                 if (err != noErr) goto exit;
  1624.                 err = SetURLListItemString(prefs, listItem);
  1625.                 if (err != noErr) goto exit;
  1626.             }
  1627.               DlgSetUserItem(dlg, kURLList, gDrawURLListUPP);
  1628.             SetItemURLSchemeName(dlg, kURLNewScheme);
  1629.             SetItemMaxLength(dlg, kURLNewScheme, kMaxSchemeNameLen);
  1630.             DlgSetCheck(dlg, kURLUseWebHelper, prefs->useWebHelperForHtmlFiles);
  1631.             AdjustURLButtons(dlg);
  1632.             break;
  1633.             
  1634.         case kTerm:
  1635.         
  1636.             prefs->useWebHelperForHtmlFiles = DlgGetCheck(dlg, kURLUseWebHelper);
  1637.             if (gURLList != nil) BigLDispose(gURLList);
  1638.             MyDisposeHandle(gURLListStrings);
  1639.             break;
  1640.             
  1641.         case kURLList:
  1642.         
  1643.             where = gCurEvent.where;
  1644.             GlobalToLocal(&where);
  1645.             BigLClick(gURLList, where, 0, &doubleClick);
  1646.             if (doubleClick) {
  1647.                 err = SetNewURLHelper(prefs);
  1648.                 if (err != noErr) goto exit;
  1649.             }
  1650.             AdjustURLButtons(dlg);
  1651.             break;
  1652.             
  1653.         case kURLChangeButton:
  1654.         
  1655.             err = SetNewURLHelper(prefs);
  1656.             if (err != noErr) goto exit;
  1657.             break;
  1658.             
  1659.         case kURLDeleteButton:
  1660.         
  1661.             listItem = BigLGetFirstSelectedItem(gURLList);
  1662.             if (listItem < 0) break;
  1663.             len = MyGetHandleSize(prefs->urlHelpers);
  1664.             BlockMoveData(
  1665.                 *prefs->urlHelpers + listItem + 1,
  1666.                 *prefs->urlHelpers + listItem,
  1667.                 len - (listItem+1) * sizeof(TURLHelperInfo));
  1668.             MySetHandleSize(prefs->urlHelpers, len - sizeof(TURLHelperInfo));
  1669.             BigLDeleteItems(gURLList, listItem, 1);
  1670.             if (listItem >= BigLGetNumItems(gURLList)) listItem--;
  1671.             if (listItem >= 0) {
  1672.                 BigLSelectOnlyOne(gURLList, listItem);
  1673.                 URLScrollIntoView();
  1674.             }
  1675.             AdjustURLButtons(dlg);
  1676.             break;
  1677.             
  1678.         case kURLNewScheme:
  1679.         
  1680.             AdjustURLButtons(dlg);
  1681.             break;
  1682.             
  1683.         case kURLAddButton:
  1684.         
  1685.             DlgGetCString(dlg, kURLNewScheme, schemeName);
  1686.             if (*schemeName == 0) break;
  1687.             for (c = schemeName; *c != 0; c++) *c = tolower(*c);
  1688.             if (MyStrCmp(schemeName, "nntp") == 0 || MyStrCmp(schemeName, "news") == 0 ||
  1689.                 MyStrCmp(schemeName, "mailto") == 0) 
  1690.             {
  1691.                 StopAlertNumber(kStrCantRedefineBuiltinURLs);
  1692.                 return noErr;
  1693.             }
  1694.             for (listItem = 0, p = *prefs->urlHelpers; *p->schemeName != 0; listItem++, p++) {
  1695.                 cmp = MyStrCmp(schemeName, p->schemeName);
  1696.                 if (cmp < 0) break;
  1697.                 if (cmp == 0) {
  1698.                     BigLSelectOnlyOne(gURLList, listItem);
  1699.                     URLScrollIntoView();
  1700.                     GetCString(kStrURLSchemeAlreadyDefined, fmt);
  1701.                     sprintf(msg, fmt, schemeName);
  1702.                     StopAlertMessage(msg);
  1703.                     return noErr;
  1704.                 }
  1705.             }
  1706.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1707.             if (!reply.sfGood) return noErr;
  1708.             if (!ValidHelper(&reply.sfFile)) return noErr;
  1709.             if (ValidURLHelper(&reply.sfFile, &newHelper)) {
  1710.                 len = MyGetHandleSize(prefs->urlHelpers);
  1711.                 err = MySetHandleSize(prefs->urlHelpers, len + sizeof(TURLHelperInfo));
  1712.                 if (err != noErr) goto exit;
  1713.                 BlockMoveData(
  1714.                     *prefs->urlHelpers + listItem,
  1715.                     *prefs->urlHelpers + listItem + 1,
  1716.                     len - listItem * sizeof(TURLHelperInfo));
  1717.                 strcpy(newHelper.schemeName, schemeName);
  1718.                 (*prefs->urlHelpers)[listItem] = newHelper;
  1719.                 err = BigLAddItems(gURLList, listItem, 1);
  1720.                 if (err != noErr) goto exit;
  1721.                 err = SetURLListItemString(prefs, listItem);
  1722.                 if (err != noErr) goto exit;
  1723.                 BigLSelectOnlyOne(gURLList, listItem);
  1724.                 URLScrollIntoView();
  1725.                 DlgSetCString(dlg, kURLNewScheme, "");
  1726.                 AdjustURLButtons(dlg);
  1727.             }
  1728.             break;
  1729.         
  1730.         case kURLUseWebHelper:
  1731.         
  1732.             DlgToggleCheck(dlg, item);
  1733.             break;
  1734.     }
  1735.     
  1736.     return noErr;
  1737.     
  1738. exit:
  1739.  
  1740.     if (gURLList != nil) BigLDispose(gURLList);
  1741.     MyDisposeHandle(gURLListStrings);
  1742.     return err;
  1743. }
  1744.  
  1745.  
  1746.  
  1747. /*----------------------------------------------------------------------------
  1748.     Auth
  1749.  
  1750.     Handles the authorization preferences dialog.
  1751.     
  1752.     Entry:    prefs = pointer to new prefs.
  1753.             dlg = pointer to dialog.
  1754.             item = item number hit.
  1755.             
  1756.     Exit:    function result = error code.
  1757. ----------------------------------------------------------------------------*/
  1758.  
  1759. static OSErr Auth (TPrefRec *prefs, DialogPtr dlg, short item)
  1760. {
  1761.     CStr255 tempStr;
  1762.     short len;
  1763.  
  1764.     switch (item) {
  1765.     
  1766.         case kInit:
  1767.  
  1768.             DlgSetCString(dlg, kAuthUsername, prefs->authUsername);
  1769.             SetItemUSAsciiNoBlank(dlg, kAuthUsername);
  1770.             SetItemMaxLength(dlg, kAuthUsername, 31);
  1771.             len = strlen(prefs->authPassword);
  1772.             memset(tempStr, '•', len);
  1773.             tempStr[len] = 0;
  1774.             DlgSetCString(dlg, kAuthPassword, tempStr);
  1775.             SetItemPassword(dlg, kAuthPassword, prefs->authPassword);
  1776.             SetItemMaxLength(dlg, kAuthPassword, 31);
  1777.             DlgSetCheck(dlg, kAuthSavePassword, prefs->authSavePassword);
  1778.             DlgSetCheck(dlg, kAuthPrivateGroups, prefs->authPrivateGroups);
  1779.             DlgSetCtlValue(dlg, prefs->authAtStartup ? kAuthAtStartup : 
  1780.                 kAuthWhenRequested, 1);
  1781.             if (*prefs->authUsername == 0) {
  1782.                 SelectDialogItemText(dlg, kAuthUsername, 0, 0);
  1783.             } else if (*prefs->authPassword == 0) {
  1784.                 SelectDialogItemText(dlg, kAuthPassword, 0, 0);
  1785.             } else {
  1786.                 SelectDialogItemText(dlg, kAuthUsername, 0, kMaxShort);
  1787.             }
  1788.             break;
  1789.             
  1790.         case kTerm:
  1791.             
  1792.             DlgGetCString(dlg, kAuthUsername, prefs->authUsername);
  1793.             prefs->authSavePassword = DlgGetCheck(dlg, kAuthSavePassword);
  1794.             prefs->authPrivateGroups = DlgGetCheck(dlg, kAuthPrivateGroups);
  1795.             prefs->authAtStartup = DlgGetCtlValue(dlg, kAuthAtStartup) == 1;
  1796.             break;
  1797.         
  1798.         case kAuthSavePassword:
  1799.         case kAuthPrivateGroups:
  1800.         
  1801.             DlgToggleCheck(dlg, item);
  1802.             break;
  1803.         
  1804.         case kAuthAtStartup:
  1805.         
  1806.             if (DlgGetCtlValue(dlg, kAuthAtStartup) == 0) {
  1807.                 DlgSetCtlValue(dlg, kAuthAtStartup, 1);
  1808.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 0);
  1809.             }
  1810.             break;
  1811.             
  1812.         case kAuthWhenRequested:
  1813.         
  1814.             if (DlgGetCtlValue(dlg, kAuthWhenRequested) == 0) {
  1815.                 DlgSetCtlValue(dlg, kAuthWhenRequested, 1);
  1816.                 DlgSetCtlValue(dlg, kAuthAtStartup, 0);
  1817.             }
  1818.             break;
  1819.             
  1820.     }
  1821.     
  1822.     return noErr;
  1823. }
  1824.  
  1825.  
  1826.  
  1827. /*----------------------------------------------------------------------------
  1828.     Extract
  1829.  
  1830.     Handles the extracting binaries preferences dialog.
  1831.     
  1832.     Entry:    prefs = pointer to new prefs.
  1833.             dlg = pointer to dialog.
  1834.             item = item number hit.
  1835.             
  1836.     Exit:    function result = error code.
  1837. ----------------------------------------------------------------------------*/
  1838.  
  1839. static OSErr Extract (TPrefRec *prefs, DialogPtr dlg, short item)
  1840. {
  1841.     StandardFileReply reply;
  1842.     FInfo fInfo;
  1843.     long dirID;
  1844.     Str31 name;
  1845.     OSErr err = noErr;
  1846.     CInfoPBRec pb;
  1847.     Boolean valid;
  1848.     AliasHandle alias;
  1849.  
  1850.     switch (item) {
  1851.     
  1852.         case kInit:
  1853.  
  1854.             DlgSetCheck(dlg, kSavedBinDirCheckBox, prefs->savedBinDefaultFolder);
  1855.               DlgSetUserItem(dlg, kSavedBinDirBorder, gDlgGrayBorderItemUPP);            
  1856.             ValidateSavedFolderAlias(prefs->savedBinDefaultFolderAlias,
  1857.                 &pb.dirInfo.ioVRefNum, &pb.dirInfo.ioDrDirID, &valid);
  1858.               if (valid) {
  1859.                 pb.dirInfo.ioNamePtr = name;
  1860.                 pb.dirInfo.ioFDirIndex = -1;
  1861.                 PBGetCatInfo(&pb, false);
  1862.             } else {
  1863.                 *name = 0;
  1864.             }
  1865.             DlgSetPString(dlg, kSavedBinDirName, name);
  1866.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1867.             
  1868.               DlgSetUserItem(dlg, kHqxAppBorder, gDlgGrayBorderItemUPP);
  1869.               err = FindAppNameFromSig(prefs->hqxHelper, name);
  1870.               if (err == noErr) {
  1871.                   DlgSetPString(dlg, kHqxAppName, name);
  1872.                   CopyPascalString(prefs->hqxHelperName, name);
  1873.               } else {
  1874.                 DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1875.             }
  1876.             
  1877.               DlgSetUserItem(dlg, kUUAppBorder, gDlgGrayBorderItemUPP);
  1878.               err = FindAppNameFromSig(prefs->uuHelper, name);
  1879.               if (err == noErr) {
  1880.                   DlgSetPString(dlg, kUUAppName, name);
  1881.                   CopyPascalString(prefs->uuHelperName, name);
  1882.               } else {
  1883.                 DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1884.             }
  1885.                 
  1886.             break;
  1887.             
  1888.         case kTerm:
  1889.         
  1890.             break;
  1891.             
  1892.         case kSavedBinDirCheckBox:
  1893.         
  1894.             DlgToggleCheck(dlg, item);
  1895.             prefs->savedBinDefaultFolder = DlgGetCheck(dlg, item);
  1896.             DlgEnableItem(dlg, kSavedBinDirButton, prefs->savedBinDefaultFolder);
  1897.             break;
  1898.             
  1899.         case kSavedBinDirButton:
  1900.         
  1901.             MyStandardGetDirectory(&reply, &dirID);
  1902.             if (!reply.sfGood) break;
  1903.             err = NewAlias(nil, &reply.sfFile, &alias);
  1904.             if (err == noErr) {
  1905.                 MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  1906.                 prefs->savedBinDefaultFolderAlias = alias;
  1907.             }
  1908.             DlgSetPString(dlg, kSavedBinDirName, reply.sfFile.name);
  1909.             break;
  1910.             
  1911.         case kHqxAppButton:
  1912.         
  1913.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1914.             if (!reply.sfGood) break;
  1915.             if (!ValidHelper(&reply.sfFile)) break;
  1916.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1917.             prefs->hqxHelper = fInfo.fdCreator;
  1918.             CopyPascalString(prefs->hqxHelperName, reply.sfFile.name);
  1919.             DlgSetPString(dlg, kHqxAppName, prefs->hqxHelperName);
  1920.             break;            
  1921.             
  1922.         case kUUAppButton:
  1923.         
  1924.             MyStandardGetFile(gInvisibleFilesFilterUPP, 2, "APPLadrp", &reply, nil);
  1925.             if (!reply.sfGood) break;
  1926.             if (!ValidHelper(&reply.sfFile)) break;
  1927.             FSpGetFInfo(&reply.sfFile, &fInfo);
  1928.             prefs->uuHelper = fInfo.fdCreator;
  1929.             CopyPascalString(prefs->uuHelperName, reply.sfFile.name);
  1930.             DlgSetPString(dlg, kUUAppName, prefs->uuHelperName);
  1931.             break;            
  1932.             
  1933.     }
  1934.     
  1935.     return noErr;
  1936. }
  1937.  
  1938.  
  1939.  
  1940. /*----------------------------------------------------------------------------
  1941.     MiscOptions
  1942.  
  1943.     Handle the miscellaneous options preferences dialog.
  1944.     
  1945.     Entry:    prefs = pointer to new prefs.
  1946.             dlg = pointer to dialog.
  1947.             item = item number hit.
  1948.             
  1949.     Exit:    function result = error code.
  1950. ----------------------------------------------------------------------------*/
  1951.  
  1952. static OSErr MiscOptions (TPrefRec *prefs, DialogPtr dlg, short item)
  1953. {
  1954.     switch (item) {
  1955.     
  1956.         case kInit:
  1957.         
  1958.             DlgSetCheck(dlg, kReZoomWindows, prefs->reZoomWindows);
  1959.             DlgSetCheck(dlg, kCheckNewGroups, prefs->checkForNewGroups);
  1960.             DlgSetCheck(dlg, kAreYouSure, prefs->areYouSureAlert);
  1961.             DlgSetCheck(dlg, kLogActionsToFile, prefs->logActionsToFile);
  1962.             DlgSetCheck(dlg, kDontCoverFinderIcons, prefs->dontCoverFinderIcons);
  1963.             DlgSetCheck(dlg, kUseInternetConfig, prefs->useInternetConfig);
  1964.             break;
  1965.             
  1966.         case kTerm:
  1967.             
  1968.             prefs->reZoomWindows = DlgGetCheck(dlg, kReZoomWindows);
  1969.             prefs->checkForNewGroups = DlgGetCheck(dlg, kCheckNewGroups);
  1970.             prefs->areYouSureAlert = DlgGetCheck(dlg, kAreYouSure);
  1971.             prefs->logActionsToFile = DlgGetCheck(dlg, kLogActionsToFile);
  1972.             prefs->dontCoverFinderIcons = DlgGetCheck(dlg, kDontCoverFinderIcons);
  1973.             prefs->useInternetConfig = DlgGetCheck(dlg, kUseInternetConfig);
  1974.             break;
  1975.             
  1976.         case kReZoomWindows:
  1977.         case kCheckNewGroups:
  1978.         case kAreYouSure:
  1979.         case kLogActionsToFile:
  1980.         case kDontCoverFinderIcons:
  1981.         case kUseInternetConfig:
  1982.         
  1983.             DlgToggleCheck(dlg, item);
  1984.             break;
  1985.             
  1986.     }
  1987.     
  1988.     return noErr;
  1989. }
  1990.  
  1991.  
  1992.  
  1993. /*----------------------------------------------------------------------------
  1994.     DrawGrayOutline
  1995.  
  1996.     A user item procedure to draw the gray outline.
  1997.     
  1998.     Entry:    dlg = pointer to dialog.
  1999.             item = item number of gray outline user item.
  2000. ----------------------------------------------------------------------------*/
  2001.  
  2002. static pascal void DrawGrayOutline (DialogPtr dlg, short item)
  2003. {
  2004.     Handle itemHandle;
  2005.     ControlHandle popupCtl;
  2006.     short itemType;
  2007.     Rect box, popupBox, r;
  2008.  
  2009.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  2010.     GetDialogItem(dlg, kTopicPopup, &itemType, (Handle*)&popupCtl, &popupBox);
  2011.     popupBox = (**popupCtl).contrlRect;
  2012.     r = box;
  2013.     r.bottom = r.top + 1;
  2014.     r.right = popupBox.left - 1;
  2015.     DrawGrayRect(&r);
  2016.     r = box;
  2017.     r.bottom = r.top + 1;
  2018.     r.left = popupBox.right + 5;
  2019.     DrawGrayRect(&r);
  2020.     r = box;
  2021.     r.right = r.left + 1;
  2022.     DrawGrayRect(&r);
  2023.     r = box;
  2024.     r.left = r.right - 1;
  2025.     DrawGrayRect(&r);
  2026.     r = box;
  2027.     r.top = r.bottom - 1;
  2028.     DrawGrayRect(&r);
  2029. }
  2030.  
  2031.  
  2032.  
  2033. /*----------------------------------------------------------------------------
  2034.     DrawArrows
  2035.     
  2036.     A user item procedure to draw the arrows.
  2037.     
  2038.     Entry:    dlg = pointer to dialog.
  2039.             item = item number.
  2040. ----------------------------------------------------------------------------*/
  2041.  
  2042. static pascal void DrawArrows (DialogPtr dlg, short item)
  2043. {
  2044.     short itemType;
  2045.     Handle itemHandle;
  2046.     Rect box;
  2047.  
  2048.     GetDialogItem(dlg, kArrows, &itemType, &itemHandle, &box);
  2049.     FrameRoundRect(&box, 8, 8);
  2050.     DrawArrowPair(gArrowPair);
  2051. }
  2052.  
  2053.  
  2054.  
  2055. /*----------------------------------------------------------------------------
  2056.     TrackArrowClick
  2057.     
  2058.     Track a click on the arrows user item.
  2059.     
  2060.     Entry:    dlg = pointer to dialog.
  2061.             curTopic = current topic number.
  2062.             
  2063.     Exit:    function result = new topic number.
  2064. ----------------------------------------------------------------------------*/
  2065.  
  2066. static short TrackArrowClick (DialogPtr dlg, short curTopic)
  2067. {
  2068.     short itemType;
  2069.     Rect box;
  2070.     Handle itemHandle;
  2071.     short delta;
  2072.     short newTopic;
  2073.  
  2074.     delta = TrackArrowPair(gArrowPair);
  2075.     newTopic = curTopic + delta;
  2076.     if (newTopic < 1) newTopic = 1;
  2077.     if (newTopic > kNumTopics) newTopic = kNumTopics;
  2078.     if (newTopic != curTopic) {
  2079.         GetDialogItem(dlg, kTopicPopup, &itemType, &itemHandle, &box);
  2080.         SetControlValue((ControlHandle)itemHandle, newTopic);
  2081.     }
  2082.     return newTopic;
  2083. }
  2084.  
  2085.  
  2086.  
  2087. /*----------------------------------------------------------------------------
  2088.     DoPreferences
  2089.  
  2090.     Presents the Preferences dialog.
  2091.     
  2092.     Exit:    function result = error code.
  2093. ----------------------------------------------------------------------------*/
  2094.  
  2095. OSErr DoPreferences (void)
  2096. {
  2097.     typedef OSErr (*prefsFuncPtr) (TPrefRec *prefs, DialogPtr dlg, short item);
  2098.     
  2099.     static prefsFuncPtr prefsFuncPtrs[] = {
  2100.         NewsreadingOptions,
  2101.         Server,
  2102.         ServerOptions,
  2103.         Personal,
  2104.         Signature,
  2105.         MessageOptions,
  2106.         ExtraHeaderLines,
  2107.         Remote,
  2108.         ScreenFonts,
  2109.         PrintingFont,
  2110.         SavedUGL,
  2111.         SavedArt,
  2112.         SavedMsg,
  2113.         URLHelpers,
  2114.         Auth,
  2115.         Extract,
  2116.         MiscOptions,
  2117.     };
  2118.  
  2119.     static short curTopic = kNewsreadingOptions;
  2120.     
  2121.     short newTopic;
  2122.     prefsFuncPtr theFunc;
  2123.     TPrefRec *prefs = nil;
  2124.     DialogPtr dlg = nil;
  2125.     Boolean reauthenticate = false;
  2126.     Handle theDITL;
  2127.     Point newLocn;
  2128.     OSErr err = noErr;
  2129.     GrafPtr port;
  2130.     short itemType;
  2131.     Handle itemHandle;
  2132.     Rect box, arrowRect, backwardHotRect, forwardHotRect;
  2133.     
  2134.     GetPort(&port);
  2135.     
  2136.     gArrowPair = nil;
  2137.     
  2138.     MyICReadSharedPrefs(kICAllSharedPrefs);
  2139.     err = MyNewPtr(sizeof(TPrefRec), &prefs);
  2140.     if (err != noErr) goto exit;
  2141.     *prefs = gPrefs;
  2142.     if (prefs->savedMsgDefaultFolderAlias != nil) {
  2143.         err = MyHandToHand(&prefs->savedMsgDefaultFolderAlias);
  2144.         if (err != noErr) {
  2145.             prefs->savedMsgDefaultFolderAlias = nil;
  2146.             prefs->savedArtDefaultFolderAlias = nil;
  2147.             prefs->savedBinDefaultFolderAlias = nil;
  2148.             prefs->savedUGLDefaultFolderAlias = nil;
  2149.             goto exit;
  2150.         }
  2151.     }
  2152.     if (prefs->savedArtDefaultFolderAlias != nil) {
  2153.         err = MyHandToHand(&prefs->savedArtDefaultFolderAlias);
  2154.         if (err != noErr) {
  2155.             prefs->savedArtDefaultFolderAlias = nil;
  2156.             prefs->savedBinDefaultFolderAlias = nil;
  2157.             prefs->savedUGLDefaultFolderAlias = nil;
  2158.             goto exit;
  2159.         }
  2160.     }
  2161.     if (prefs->savedBinDefaultFolderAlias != nil) {
  2162.         err = MyHandToHand(&prefs->savedBinDefaultFolderAlias);
  2163.         if (err != noErr) {
  2164.             prefs->savedBinDefaultFolderAlias = nil;
  2165.             prefs->savedUGLDefaultFolderAlias = nil;
  2166.             goto exit;
  2167.         }
  2168.     }
  2169.     if (prefs->savedUGLDefaultFolderAlias != nil) {
  2170.         err = MyHandToHand(&prefs->savedUGLDefaultFolderAlias);
  2171.         if (err != noErr) {
  2172.             prefs->savedUGLDefaultFolderAlias = nil;
  2173.             goto exit;
  2174.         }
  2175.     }
  2176.     if (prefs->urlHelpers != nil) {
  2177.         err = MyHandToHand(&prefs->urlHelpers);
  2178.         if (err != noErr) {
  2179.             prefs->urlHelpers = nil;
  2180.             goto exit;
  2181.         }
  2182.     }
  2183.  
  2184.     err = MyGetNewDialog(kPrefsDlg, ok, cancel, &dlg);
  2185.     if (err != noErr) goto exit;
  2186.     SetPort(dlg);
  2187.     RestoreMovableModalDialogPosition(dlg, gPrefs.prefsLoc);
  2188.     
  2189.     GetDialogItem(dlg, kArrows, &itemType, &itemHandle, &box);
  2190.     SetRect(&arrowRect, box.left + 2, box.top + 3, box.left + 12, box.top + 21);
  2191.     backwardHotRect = forwardHotRect = box;
  2192.     backwardHotRect.bottom = forwardHotRect.top = box.top + 13;
  2193.     backwardHotRect.top++;
  2194.     forwardHotRect.bottom++;
  2195.     err = CreateArrowPair(true, &arrowRect, &backwardHotRect,
  2196.         &forwardHotRect, &gArrowPair);
  2197.     if (err != noErr) goto exit;
  2198.     EnableOrDisableArrowPair(gArrowPair, -1, curTopic > 1);
  2199.     EnableOrDisableArrowPair(gArrowPair, +1, curTopic < kNumTopics);
  2200.     
  2201.     for (gItem = kFirstGrayLine; gItem <= kLastGrayLine; gItem++)
  2202.         DlgSetUserItem(dlg, gItem, gDlgGrayBorderItemUPP);
  2203.     DlgSetUserItem(dlg, kArrows, gDlgArrowsItemUPP);
  2204.     if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  2205.     err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  2206.     if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  2207.     InitCursor();
  2208.     if (err != noErr) goto exit;
  2209.     MyReleaseResource(theDITL);
  2210.     DlgSetCtlValue(dlg, kTopicPopup, curTopic);
  2211.     theFunc = prefsFuncPtrs[curTopic - 1];
  2212.     err = (*theFunc)(prefs, dlg, kInit);
  2213.     if (err != noErr) goto exit;
  2214.     DlgSetDefaultButtonOutline(dlg, curTopic != kSignature && curTopic != kExtraHeaderLines);
  2215.     
  2216.     while (true) {
  2217.         MyMovableModalDialog(dlg, 
  2218.             curTopic == kURLHelpers ? URLHelpersFilter : DialogFilter, 
  2219.             &gItem);
  2220.         if (gItem == ok || gItem == cancel) {
  2221.             gValid = true;
  2222.             err = (*theFunc)(prefs, dlg, kTerm);
  2223.             if (err != noErr) goto exit;
  2224.             if (gValid || gItem == cancel) break;
  2225.         } else if (gItem == kTopicPopup || gItem == kArrows) {
  2226.             if (gItem == kTopicPopup) {
  2227.                 newTopic = DlgGetCtlValue(dlg, kTopicPopup);
  2228.             } else {
  2229.                 newTopic = TrackArrowClick(dlg, curTopic);
  2230.             }
  2231.             if (newTopic != curTopic) {
  2232.                 gValid = true;
  2233.                 err = (*theFunc)(prefs, dlg, kTerm);
  2234.                 if (err != noErr) goto exit;
  2235.                 if (gValid) {
  2236.                     curTopic = newTopic;
  2237.                     EnableOrDisableArrowPair(gArrowPair, -1, curTopic > 1);
  2238.                     EnableOrDisableArrowPair(gArrowPair, +1, curTopic < kNumTopics);
  2239.                     MyShortenDITL(dlg, CountDITL(dlg) - kCommonItems);
  2240.                     if (curTopic == kScreenFonts || curTopic == kPrintingFont) SetCursor(&gWatchCurs);
  2241.                     err = MyGetResource('DITL', kPrefsDlg + curTopic, &theDITL);
  2242.                     if (err == noErr) err = MyAppendDITL(dlg, theDITL, overlayDITL);
  2243.                     InitCursor();
  2244.                     if (err != noErr) goto exit;
  2245.                     MyReleaseResource(theDITL);
  2246.                     theFunc = prefsFuncPtrs[curTopic - 1];
  2247.                     err = (*theFunc)(prefs, dlg, kInit);
  2248.                     if (err != noErr) goto exit;
  2249.                     DlgSetDefaultButtonOutline(dlg, 
  2250.                         curTopic != kSignature && curTopic != kExtraHeaderLines);
  2251.                 } else {
  2252.                     GetDialogItem(dlg, kTopicPopup, &itemType, &itemHandle, &box);
  2253.                     SetControlValue((ControlHandle)itemHandle, curTopic);
  2254.                 }    
  2255.             }
  2256.         } else {
  2257.             err = (*theFunc)(prefs, dlg, gItem);
  2258.             if (err != noErr) goto exit;
  2259.         }
  2260.     }
  2261.     
  2262.     SaveMovableModalDialogPosition(dlg, &newLocn);
  2263.     
  2264.     DisposeArrowPair(gArrowPair);
  2265.     gArrowPair = nil;
  2266.     
  2267.     err = DoClose(dlg);
  2268.     dlg = nil;
  2269.     if (err != noErr) goto exit;
  2270.     
  2271.     if (gItem == ok) {
  2272.         if (prefs->logActionsToFile && !gPrefs.logActionsToFile) {
  2273.             OpenLogFile();
  2274.         } else if (!prefs->logActionsToFile && gPrefs.logActionsToFile) {
  2275.             CloseLogFile();
  2276.         }
  2277.         if (!EqualString(prefs->newsServerName, gPrefs.newsServerName, false, true)) {
  2278.             NoteMessageNumber(kStrMustRestart);
  2279.         }
  2280.         if (prefs->useInternetConfig != gPrefs.useInternetConfig) {
  2281.             NoteMessageNumber(kStrMustRestartIC);
  2282.         }
  2283.         reauthenticate = strcmp(prefs->authUsername, gPrefs.authUsername) != 0 ||
  2284.             strcmp(prefs->authPassword, gPrefs.authPassword) != 0 ||
  2285.             prefs->authAtStartup && !gPrefs.authAtStartup;
  2286.         MyDisposeHandle(gPrefs.savedMsgDefaultFolderAlias);
  2287.         MyDisposeHandle(gPrefs.savedArtDefaultFolderAlias);
  2288.         MyDisposeHandle(gPrefs.savedBinDefaultFolderAlias);
  2289.         MyDisposeHandle(gPrefs.savedUGLDefaultFolderAlias);
  2290.         MyDisposeHandle(gPrefs.urlHelpers);
  2291.         gPrefs = *prefs;
  2292.         MyICWriteSharedPrefs(kICAllSharedPrefs);
  2293.         ResetNewsServerOptions();
  2294.         AdjustExtractBinariesCommand();
  2295.     } else {
  2296.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  2297.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  2298.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  2299.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  2300.         MyDisposeHandle(prefs->urlHelpers);
  2301.     }
  2302.     MyDisposePtr(prefs);
  2303.     prefs = nil;
  2304.     gPrefs.prefsLoc = newLocn;
  2305.     if (reauthenticate && gStartupOK) {
  2306.         err = ReAuthenticate();
  2307.         if (err != noErr) goto exit;
  2308.         if (gPrefs.authPrivateGroups) {
  2309.             err = DoRebuildFullGroupList();
  2310.             if (err != noErr) goto exit;
  2311.         }
  2312.     }
  2313.     SetPort(port);
  2314.     return noErr;
  2315.     
  2316. exit:
  2317.  
  2318.     if (gArrowPair != nil) DisposeArrowPair(gArrowPair);
  2319.     if (dlg != nil) DoClose(dlg);
  2320.     if (prefs != nil) {
  2321.         MyDisposeHandle(prefs->savedMsgDefaultFolderAlias);
  2322.         MyDisposeHandle(prefs->savedArtDefaultFolderAlias);
  2323.         MyDisposeHandle(prefs->savedBinDefaultFolderAlias);
  2324.         MyDisposeHandle(prefs->savedUGLDefaultFolderAlias);
  2325.         MyDisposeHandle(prefs->urlHelpers);
  2326.         MyDisposePtr(prefs);
  2327.     }
  2328.     SetPort(port);
  2329.     return err;
  2330. }
  2331.  
  2332.  
  2333.  
  2334. /*----------------------------------------------------------------------------
  2335.     prefsdlog_InitUPP
  2336.     
  2337.     Initialize UPPs.
  2338. ----------------------------------------------------------------------------*/
  2339.  
  2340. void prefsdlog_InitUPP (void)
  2341. {
  2342.     gInvisibleFilesFilterUPP = NewFileFilterYDProc(InvisibleFilesFilter);
  2343.     gDrawFontSampleUPP = NewUserItemProc(DrawFontSample);
  2344.     gDlgArrowsItemUPP = NewUserItemProc(DrawArrows);
  2345.     gDrawURLListUPP = NewUserItemProc(DrawURLList);
  2346. }